I have successfully made a Perlin noise algorithm on the GPU. It works as expected, and generates great results. Now, as part of the physics calculations in my game, I need to replicate the exact same algorithm on the CPU, so that I can (given an X, Y and Z coordinate) determine whether or not that is inside a wall, or a walkable area.
I have debugged the shader through PIX, and I've gotten everything almost right, except for the part below (seen in shader code).
GPU (shader) code (HLSL)
float4 perm2d(float2 p)
{
return tex2D(permSampler2d, p);
}
permSampler2d samples a texture that I generate out of Color structures and then pump to the GPU. The way I generate the texture on the CPU is the following:
CPU code (XNA C#)
int createPerm2d(int i)
{
return permutation[i % 256];
}
public Texture2D GeneratePermTexture2d()
{
permTexture2d = new Texture2D(device, 256, 256, true, SurfaceFormat.Color);
permutationData = new Color[256 * 256];
for (int x = 0; x < 256; x++)
{
for (int y = 0; y < 256; y++)
{
int A = createPerm2d(x) + y;
int AA = createPerm2d(A);
int AB = createPerm2d(A + 1);
int B = createPerm2d(x + 1) + y;
int BA = createPerm2d(B);
int BB = createPerm2d(B + 1);
permutationData[x + (y * 256)] = new Color((byte)(AA), (byte)(AB),
(byte)(BA), (byte)(BB));
}
}
permTexture2d.SetData<Color>(permutationData);
return permTexture2d;
}
As said before, all this works as expected, until I run the code on the CPU to get the noise data back later.
According to PIX, the part that fails is indeed perm2d on the CPU (as seen below), which produces incorrect results.
CPU code (XNA C#)
static Vector4 perm2d(Vector2 p)
{
return permutationData[(int)p.X + ((int)(p.Y) * 256)].ToVector4();
}
At the particular area (in the exact same pixel with the exact same seed used to generate the map, where it returns the incorrect results, PIX reports that the GPU returns "{0.035, 0.067, 0.365, 0.408}" from the perm2d function whereas the CPU code returns "{X:0,7450981 Y:0,345098 Z:0,5137255 W:0,09803922}".
Other than that, the rest of the functions produce the right outputs.